<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class AutoExecCodeCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'app:auto-exec';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    protected $code = '';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $code = 'echo \'yym\';';
        $params = [1,2,3];
        $ret = (string)$this->getFunc($code)($params);
        Log::info('app:auto-exec ret:', [$ret]);
        return 0;
    }

    private function getFunc($code)
    {
        $hash = md5($code);
        $file = './Temp/' . 'chatbot_v2_program_script_' . $hash . '.php';
        if (!file_exists($file)) {
            $content = '';
            $content .= '<?php' . PHP_EOL;
            $content .= 'return function(array &$params) {' . PHP_EOL;
            $content .= $code . PHP_EOL;
            $content .= '};' . PHP_EOL;

            file_put_contents($file, $content);
        }

        // 首次require_once时返回Closure对象，第二次require_once时，返回true
        $func = require_once $file;
        static $cache = [];
        if ($func instanceof \Closure) {
            $cache[$hash] = $func;
            return $func;
        }

        Log::info('func info', [
            'ProgramUtilGetFunc' => [
                'file' => $file,
                'type' => gettype($func),
                'func' => $func,
            ],
        ]);

        if ($func === true) {
            return $cache[$hash];
        }
    }
}
